using System.Collections.Immutable;
using System.Text.Json;

using Volo.Abp.OpenIddict.Applications;
using Volo.Abp.OpenIddict.Scopes;

using WL.Think.Abp.AutoMapper;
using WL.Think.Abp.OpenIddict.Dtos;

namespace WL.Think.Abp.OpenIddict
{
    public class OpenIddictAutoMapperProfile : AutoMapperProfile
    {
        public override void Mapping()
        {
            Map<OpenIddictScope, ScopeDto>()
                .ForMember(
                    x => x.Resources,
                    s => s.MapFrom(d => ToHashSet(d.Resources))
                );

            Map<OpenIddictApplication, ApplicationDto>()
                .ForMember(
                    x => x.Permissions,
                    s => s.MapFrom(d => ToHashSet(d.Permissions))
                )
                .ForMember(
                    x => x.PostLogoutRedirectUris,
                    s => s.MapFrom(d => ToHashSet(d.PostLogoutRedirectUris))
                )
                .ForMember(
                    x => x.RedirectUris,
                    s => s.MapFrom(d => ToHashSet(d.RedirectUris))
                );

            Map<ApplicationDto, ApplicationCreateUpdateDto>();
            Map<ScopeDto, ScopeCreateUpdateDto>();
        }

        private HashSet<string> ToHashSet(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return new HashSet<string>() ;
            }

            using (var document = JsonDocument.Parse(value))
            {
                var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());

                foreach (var element in document.RootElement.EnumerateArray())
                {
                    var v = element.GetString();
                    if (string.IsNullOrEmpty(v))
                    {
                        continue;
                    }

                    builder.Add(v);
                }

                return [.. builder.ToImmutable()];
            }
        }
    }
}
